package controllers

import (
	"net/http"
	"strconv"
	"time"
	"xinmanpan/app/models"
	"xinmanpan/utils"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

type EmailController struct {
	BaseController
}

func NewEmailController(db *gorm.DB) *EmailController {
	return &EmailController{
		BaseController{
			DB: db,
		},
	}
}

func (ec *EmailController) updateSmtpSetting(smtpSetting models.XinmanSmtpSetting) error {
	// Always update the first and only record
	return ec.DB.Model(&models.XinmanSmtpSetting{}).Where("id = ?", 1).Updates(smtpSetting).Error
}

func (ec *EmailController) SendVerificationCodeByEmail(c *gin.Context) {
	var smtpData models.XinmanSmtpSetting
	if err := c.ShouldBindJSON(&smtpData); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
		return
	}
	// email := c.PostForm("email")
	email := smtpData.Username
	if email == "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": "email is required"})
		return
	}

	// 生成验证码
	code := utils.GenerateRandomCode(4)
	// 查询SmtpSetting表,获取SMTP配置信息
	var smtpConfig models.XinmanSmtpSetting
	if err := ec.DB.Where("id = ?", 1).First(&smtpConfig).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to retrieve SMTP configuration"})
		return
	}
	// 解密加密的密码
	pssword, err := utils.Decrypt(smtpConfig.Password)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to decrypt password"})
		return
	}
	smtpConfig.Password = pssword

	// 准备邮件内容
	subject := "您的验证码"
	body := "您的验证码是: " + code

	// 发送邮件
	if smtpConfig.Encryption == "ssl" {
		err := utils.SendEmailWithSSL(smtpConfig.Host, strconv.Itoa(smtpConfig.Port), smtpConfig.Username, smtpConfig.Password, email, subject, body)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to send verification email"})
			return
		}
	} else {
		err := utils.SendEmailWithoutSSL(smtpConfig.Host, strconv.Itoa(smtpConfig.Port), smtpConfig.Username, smtpConfig.Password, email, subject, body)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to send verification email"})
			return
		}
	}

	// 数据库存在记录则更新，不存在则创建
	var existingVerificationCode models.XinmanEmailVerificationCode
	err = ec.DB.Where("email = ?", email).First(&existingVerificationCode).Error

	// 保存验证码到数据库
	var verificationCode models.XinmanEmailVerificationCode
	verificationCode.Uuid = utils.GetUUID()
	verificationCode.Sort = time.Now().UnixNano()
	verificationCode.Email = email
	verificationCode.Code = code
	verificationCode.ExpirationTime = time.Now().Add(time.Minute * 5)
	verificationCode.IsUsed = 0
	verificationCode.UpdateTime = time.Now()

	if err != nil {
		if err == gorm.ErrRecordNotFound {
			verificationCode.CreateTime = time.Now()
			if err := ec.DB.Create(&verificationCode).Error; err != nil {
				c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save verification code"})
				return
			}

		} else {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to save verification code"})
			return
		}

	} else {
		// 更新记录
		err = ec.DB.Model(&existingVerificationCode).Where("email = ?", email).Updates(verificationCode).Error
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update verification code"})
			return
		}
	}

	c.JSON(http.StatusOK, gin.H{"message": "Verification email sent successfully"})

}

func (ec *EmailController) UpdateXinmanSmtpSetting(c *gin.Context) {

	var smtpData models.XinmanSmtpSetting
	if err := c.ShouldBindJSON(&smtpData); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
		return
	}

	password, err := utils.Encrypt(smtpData.Password)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to encrypt password"})
		return
	}
	smtpData.Password = password

	if err := ec.updateSmtpSetting(smtpData); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update SMTP setting"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "SMTP setting updated successfully"})

}

func (ec *EmailController) GetXinmanSmtpSetting(c *gin.Context) {

	var smtpSetting models.XinmanSmtpSetting
	if err := ec.DB.Where("id = ?", 1).First(&smtpSetting).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to retrieve SMTP setting"})
		return
	}
	password, err := utils.Decrypt(smtpSetting.Password)
	smtpSetting.Password = password
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to decrypt password"})
		return
	}

	c.JSON(http.StatusOK, smtpSetting)

}

func (ec *EmailController) VerifyEmailCode(c *gin.Context) {

	var codeData models.XinmanEmailVerificationCode

	if err := c.ShouldBindJSON(&codeData); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
		return
	}

	var verificationCode models.XinmanEmailVerificationCode
	if err := ec.DB.Where("email = ? AND code = ? AND is_used = 0", codeData.Email, codeData.Code).First(&verificationCode).Error; err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid verification code"})
		return
	}

	if verificationCode.ExpirationTime.Before(time.Now()) {
		c.JSON(http.StatusBadRequest, gin.H{"error": "Verification code has expired"})
		return
	}

	verificationCode.IsUsed = 1
	verificationCode.UpdateTime = time.Now()

	if err := ec.DB.Save(&verificationCode).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to update verification code"})
		return
	}

	c.JSON(http.StatusOK, gin.H{"message": "Verification code verified successfully"})
}
